#pragma once

#include "discovery/eventfd_receiver.h"
#include <boost/asio/posix/stream_descriptor.hpp>
#include <boost/asio/steady_timer.hpp>
#include <memory>
#include <vector>
#include <mutex>
#include <chrono>

using namespace boost::asio;

/**
 * 扩展的EventFD传递回调，包含消息信息
 */
using ExtendedTransferCallback = std::function<void(const boost::system::error_code&, int eventfd, const TransferMessage& msg)>;

/**
 * EventFD Domain Socket 接收器（服务端）
 */
class EventFdDomainSocketReceiver : public EventFdReceiver {
private:
    
    struct ConnectionInfo {
        int socket_fd;
        std::unique_ptr<posix::stream_descriptor> descriptor;
        std::string peer_info;
        std::chrono::steady_clock::time_point connect_time;
        
        ConnectionInfo();
        void reset();
    };

public:
    explicit EventFdDomainSocketReceiver(io_context& io, 
                                       const std::string& socket_path,
                                       const std::string& identifier = "eventfd_transfer");
    ~EventFdDomainSocketReceiver() override;
    
    bool start() override;
    void stop() override;
    
    /**
     * 设置扩展的传递回调（包含消息信息）
     */
    void set_extended_transfer_callback(ExtendedTransferCallback callback);
    
    /**
     * 获取连接数量
     */
    size_t connection_count() const;

private:
    std::string socket_path_;
    int server_socket_;
    std::unique_ptr<posix::stream_descriptor> server_descriptor_;
    std::vector<std::unique_ptr<ConnectionInfo>> connections_;
    std::unique_ptr<steady_timer> cleanup_timer_;
    std::chrono::milliseconds cleanup_interval_{3000};
    mutable std::mutex connections_mutex_;
    ExtendedTransferCallback extended_transfer_callback_;  // 扩展回调
    
    bool start_server();
    void start_accept();
    void handle_accept();
    void start_receive_eventfd(ConnectionInfo* connection);
    void receive_eventfd_from_connection(ConnectionInfo* connection, TransferMessage& received_msg);
    void start_cleanup_timer();
    void cleanup_dead_connections();
    void remove_connection(ConnectionInfo* target);
    int recv_fd(int socket_fd);
    int recv_fd_with_info(int socket_fd, TransferMessage& msg);
};
